返回首页
知识点
递归取数
;WITH ent
AS (SELECT EntryID,0 AS _parentId
FROM #LevelOne
UNION ALL
SELECT a.EntryID,a._parentId
FROM #Result a
INNER JOIN ent b ON a._parentId=b.EntryID
)
SELECT DISTINCT EntryID INTO #TopToBottom FROM ent
其实UNION ALL前的语句相当于初始化值,然后决定这些值是向上OR向下递归
知识点
DECLARE @sql VARCHAR(1000)
SET @sql='SELECT
1234 AS Col1
4321 AS Col2'
PRINT @sql
EXEC (@sql)
动态别名只能用动态语句
知识点
反转字符串
SELECT REVERSE('abc')
高速
--查询死锁
select request_session_id 锁表进程,OBJECT_NAME(resource_associated_entity_id) 被锁表名
from sys.dm_tran_locks where resource_type='OBJECT'
--处理死锁
declare @spid int
Set @spid=60 --锁表进程
declare @sql varchar(1000)
set @sql='kill '+cast(@spid as varchar)
exec (@sql)
知识点
Between..AND..
包括两边的边界值 可以为数值、文本、日期(注意是当天0点)
知识点
使用Exists条件而不用inner join 或 其他join 是因为可能有多条匹配
包括两边的边界值 可以为数值、文本、日期(注意是当天0点)
高速
游标样例
DECLARE @ProCode NVARCHAR(50);
DECLARE @UserId NVARCHAR(50);
DECLARE @Count INT;
BEGIN
DECLARE Update_cursora CURSOR LOCAL static read_only forward_only FOR
select ProductCodeId,UserCode from Product_User_Relation where DeleteFlag =0 and ProductCodeId like '9%' ---And UserCode='duanjin 06481'
OPEN Update_cursora;
FETCH NEXT FROM Update_cursora INTO @ProCode,@UserId
WHILE @@FETCH_STATUS = 0
BEGIN
select * into #temp from (
select ProID,ProCode FROM dbo.ProductInfo where ParentCode=@ProCode --A
--B
union all
select ProID,ProCode FROM ProductInfo where ParentCode in(
select ProCode from dbo.ProductInfo where ParentCode=@ProCode
)
union all
--C
select ProID,ProCode FROM ProductInfo where ParentCode in(
select ProCode from ProductInfo where ParentCode in(
select ProCode from ProductInfo where ParentCode=@ProCode
)
)
)pro
where not exists(select 1 from Product_User_Relation where UserCode=@UserId And pro.ProCode=ProductCodeId);
DROP TABLE #temp
FETCH NEXT FROM Update_cursora INTO @ProCode,@UserId
END;
CLOSE Update_cursora;
DEALLOCATE Update_cursora;
END;
高速
压缩日志
USE[PersonalInput]
GO
ALTER DATABASE PersonalInput SET RECOVERY SIMPLE WITH NO_WAIT
GO
ALTER DATABASE PersonalInput SET RECOVERY SIMPLE --简单模式
GO
USE PersonalInput
GO
DBCC SHRINKFILE (N'PersonalInput_log' , 2, TRUNCATEONLY) --设置压缩后的日志大小为2M,可以自行指定
GO
USE[PersonalInput] -- 注意要把使用的数据库不是master 还原为完整模式
GO
ALTER DATABASE PersonalInput SET RECOVERY FULL WITH NO_WAIT
GO
ALTER DATABASE PersonalInput SET RECOVERY FULL --还原为完全模式
GO
高速
更新统计信息
--更新库所有表的统计信息
--EXEC sp_updatestats
go
--更新某一个表的统计信息
UPDATE STATISTICS Sales.SalesOrderDetail;
GO
--更新某一个索引的统计信息
UPDATE STATISTICS Sales.SalesOrderDetail AK_SalesOrderDetail_rowguid;
高速
查询表字段
select * from sys.columns where object_id=object_id('table_name')
sys.columns - 保存当前数据库中所有表的所有字段
object_id('objectname') 返回对象的ID值
高速
表更新相关
--根据不同条件 把某列值更新为其他值
UPDATE Table SET Column=
CASE WHEN Column=Value
THEN Value
WHEN Column=Value
THEN Value END
--根据两个表关联条件 把其中一个表中字段数据更新到另一个表的字段中
UPDATE TableA
SET TableA.Column=B.Column
FROM TableB B WHERE TableA.Column=B.Column
-- 使用别名
UPDATE ent
SET EntryCName=bak.EntryCName,
PriorityLevel=bak.PriorityLevel,
Remark=bak.Remark,
Description=bak.Description,
Status=0,
DeleteFlag=0
FROM Sol_Entry bak
INNER JOIN Sol_EntryRelation rel ON bak.EntryID=rel.BackEntryID
INNER JOIN Sol_Entry ent ON ent.EntryID=rel.EntryID WHERE ent.BlID=4
AND bak.Status=-2
--update 和from 来自同一个表时 update后必须用别名 from 后用inner join
UPDATE col
SET col.Name=bak.Name,
col.Description=bak.Description,
col.Status=0
FROM Sol_EntryColName bak
INNER JOIN Sol_EntryColName col ON col.ColID=bak.BackColID
WHERE bak.Status=-2 AND Sol_EntryColName.BlID=:BlID
高速
表删除相关
DELETE ent
FROM TableA ent
INNER JOIN TableB rel ON ent.ID=rel.ID
WHERE rel.Type=1
知识点
查询表上依赖关系
在表上右键 有个依赖关系 点击后能看到依赖的表,函数,存储过程,视图 如果某个字段更新了(字段大小改变等) 像视图之类的依赖关系必须更新
额外注意存储过程中遇到拼接字符串的表名是查询不到依赖关系的,只有sql语句中可以查到
高速
创建存储过程
-- =============================================
-- Author:
-- Create date:
-- Description: 获取产品工程类型数据及产品列
-- =============================================
ALTER PROCEDURE [dbo].[P_GetProductCol]
@blId INT, --基线id
@userId NVARCHAR(100),
--用户工号 e.g ys2338 ,17333 @proAttr NVARCHAR(100),
--产品列内容 查询条件,传递的是字典表的ConsValue,e.g:UnSupport,Other
@isEdit bit,--0:不是编辑 1是编辑
@showType INT -- 类型 0:产品列名称显示 1:使用Pro_ 列ID (为前端处理方便)
AS BEGIN
DECLARE @procol VARCHAR(max) --有权限的产品列
DECLARE @sql VARCHAR(max)
--拼接的sql exec(@sql)
--select @sql END;
知识点
CHARINDEX的使用
select charindex('a','abca')
result :1
从左到右只返回第一个匹配到的节点,下标从1开始 该函数无法使用索引
小坑
left join 的使用
一个主表main left join 业务表T1 如要保持主表完整性,筛选条件要跟在T1后,不能放到主表where 条件中,否则是筛选主表了
高速
检查是否有临时表
if object_id(N'tempdb..#K_Temp',N'U') is not null
begin
Table #K_Temp
print '删除成功'
end
高速
查询表创建时间
select distinct xtype from sysobjects
-- select name,crdate from sysobjects where xtype = 'TF' --表值函数
-- select name,crdate from sysobjects where xtype = 'FN' --标量值函数
-- select name,crdate from sysobjects where xtype = 'P' --存储过程
-- select name,crdate from sysobjects where xtype = 'U' --表
-- select name,crdate from sysobjects where xtype = 'V' -- 视图
知识点
行转列函数定义
SELECT ,
[first pivoted column] AS ,
[second pivoted column] AS ,
…
[last pivoted column] AS
FROM
(<查询表或者子查询作为数据源>)
AS 表别名
PIVOT
(
<聚合函数>(<被聚合的列>)(原有的数据列)
FOR
[<待转换的列名称,此列的多个唯一值将被转换为列标题>(转换前列名)]
IN ( [first pivoted column], [second pivoted column],
… [last pivoted column])
) AS <旋转表的别名>
<可选的排序子句 order by >;
高速
行转列例子一则
if object_id('tempdb..#test') is not null
drop table #test
create table #test
( 事项名称 varchar(200),
年月 varchar(7),
受理数量 int ,
办结数量 int
)
insert into #test
select '注销','2019-01',77,77
union all
select '注销','2019-02',66,77
union all
select '延续','2019-03',16,16
union all
select '注销','2019-04',16,16
union all
select '延续','2019-04',120,115
--select *from #test
declare @event varchar(3000)='',@sql varchar(3000)='',@queryexp varchar(3000)=''
if object_id('tempdb..#hbTab') is not null
drop table #hbtab
select 事项名称,(年月+'_受理') as [year],受理数量,年月 into #hbtab from #test
--列转行
insert into #hbtab
select 事项名称,(年月+'_办结') as [year],办结数量,年月 from #test
--获取行的属性
--select *from #hbtab
select @event=@event+',['+[year]+']' from (select distinct [year] from #hbtab) a order by [year]
select @queryexp=@queryexp+',max(['+[year]+']) as '+'['+[year]+']' from (select distinct [year] from #hbtab) a order by [year]
select @queryexp=right(@queryexp,len(@queryexp)-1)
select @event=right(@event,len(@event)-1)
--select *from #hbtab order by year
set @sql='select 事项名称,'+@queryexp+' from( select 事项名称,'+@event +'from #hbtab a
pivot (max(受理数量) for year in('+@event+')
) as pv ) b group by 事项名称'
print @sql
exec(@sql)
原文:https://blog.csdn.net/u010892506/article/details/89458862
高速
逗号分隔的字符串转换为Table数据
DECLARE @person VARCHAR(300)='liuyujing,liufeng,zhaiguoxiu'
DECLARE @tmpsql NVARCHAR(4000)
SELECT @tmpsql='SELECT ''' + REPLACE(@person,',',''' UNION ALL SELECT ''')+ ''''
PRINT @tmpsql
exec sp_executesql @tmpsql
坑
临时表或表无索引时 插入有序数据(按字符串列排序) 在临时表或表中是无序的
1.可以创建索引解决 Create Clustered Index IDX_Table_Name ON Table(name)
2.可以引入新的排序后的序号列解决 select ROW_NUMBER() over(order by oi.CreatedOn desc) as row_num,oi.Id,odi.Amount...
坑
字符串变量为null的问题
定义变量后declare @str nvarchar(10) 不赋值则是null 如果再有字符串相关的拼接操作 则结果很有可能都为null
所以需要设置set @str=''
知识点
函数DatePart 返回日期/时间单独部分 DATEPART(datepart,date)
年 yy, yyyy
季度 qq, q
月 mm, m
年中的日 dy, y
日 dd, d
周 wk, ww
星期 dw, w
小时 hh
分钟 mi, n
秒 ss, s
毫秒 ms
微妙 mcs
纳秒 ns
问题
查询处理器用尽了内部资源,无法生成查询计划
在项目中动态拼接sql语句,使用union all连接结果集,每个查询语句都使用了in(几百个数值)
SELECT AA FROM T1 WHERE aa IN(1,2,3,4..............................)
UNION ALL
SELECT AA FROM T2 WHERE aa IN(1,2,3,4..............................)
主要是因为IN中数据量太大了 解决方案:使用临时表把in语句改成EXISTS语句
知识点
嵌套的事务
1.如果出现rollback tran 之类的是回滚所有 并不区分是内层还是外层 后面语句如果再有commit或rollback 会报错:‘COMMIT TRANSACTION 请求没有对应的 BEGIN TRANSACTION’ 所以内层rollback 往往跟return
2.如果没有save tran innerTran 想回滚内层 rollback tran innerTran 是报错的
3.内层save tran innerTran1 或save tran innerTran2 可以使用rollback tran innerTran1(回到这个状态)
4.只要外层rollback tran 内层不管什么状态都是回滚
知识点
select * from 多个表的写法
from 多个表后没有添加任何的关联条件 其实就是笛卡尔积 应避免该种写法 如果遇到 大多是错误的写法
知识点
Merge 语句的使用
根据与源表联接的结果,对目标表运行插入、更新或删除操作。 语法如下:
[ WITH [,...n] ]
MERGE
[ TOP ( expression ) [ PERCENT ] ]
[ INTO ] [ WITH ( ) ] [ [ AS ] table_alias ]
USING [ [ AS ] table_alias ]
ON
[ WHEN MATCHED [ AND ]
THEN ] [ ...n ]
[ WHEN NOT MATCHED [ BY TARGET ] [ AND ]
THEN ]
[ WHEN NOT MATCHED BY SOURCE [ AND ]
THEN ] [ ...n ]
[ ]
[ OPTION ( [ ,...n ] ) ]
;
其中 using 后的源 可以是多个表的关联;注意最后需要有分号
::=
{ UPDATE SET | DELETE }
::=
{
INSERT [ ( column_list ) ]
{ VALUES ( values_list )
| DEFAULT VALUES }
}
注意:无论哪种操作,都只能操作目标表;当为NOT MATCHED BY SOURCE 状态时,不能使用源表中的数据,即不能更新为源表中某个字段的内容,但可以指定一个常量
举个例子
merge TestB T
using TestC S
on T.entryid=s.entryid
when matched
then update set T.Des=S.Des
when not matched
then insert values(S.entryid,S.Des)
when not matched by source
then delete
;
知识点
Stuff 函数
它从第一个字符串的开始位置删除指定长度的字符;然后将第二个字符串插入到第一个字符串的开始位置。
语法:STUFF(character_expression , start , length , replaceWith_expression)
start 参数:
一个整数值(从1开始),指定删除和插入的开始位置。start 的类型可以是 bigint。
SELECT STUFF('abc',2,1,'EFG')
结果:aEFGc
知识点
For XML Path
该方式其实是用xml节点名称包装记录,展示为一条数据
默认情况下,最外层节点为Row,内层节点则是列的名称,举个例子:
SELECT T1 FROM TABLE For XML Path 的结果为:
1
2
也可以用For XML Path('') 不要最外层的row节点
当选择的列有计算时,如数字的加减,字符串的拼接,则该列被当作新列,没有名称!所以For XML Path 的用途一般为高效拼接字符串,举个例子:
SELECT STUFF((SELECT ','+T1 From TABLE For XML Path('')),1,1,'')
该语句的作用为用逗号分隔T1列中拼接的内容
知识点
表中一列字符串累加的处理
e.g 从表T中选择Name列,Name列有三行值为a,b,c
declare @str nvarchar(1000) SET @str=''
select @str= @str+ CONVERT(nvarchar(50), ISNULL(Name,' ')) +',' from T
select @str
结果:a,b,c,
该方法与For XML Path的结果基本相同,但没有它高效
知识点
变量处理列内容累加
比如,用分号分隔一列内容累加
declare @str nvarchar(1000)
select @str= CONVERT(nvarchar, ISNULL(@str,''))+CONVERT(nvarchar, ISNULL(column,' ')) +';'
from table
select @str
注意 1.需要定义变量存放值
2.不能从table中选择多列,否则语法有错误
知识点
必须指定别名的情况
select t.* from(select 1 as t1) t
这种选择常量的,内层必须指定别名 否则会报:没有为 't' 的列 1 指定任何列名称
知识点
优化经验
1.先弄懂业务 以及表之间的关系 确保各条件分支业务逻辑正确
2.通过查看预读,逻辑读,物理读次数找到耗时点
3.对于临时表 可以建立索引加快查询 (优化近20s)
4.查看执行计划 找出消耗占比大的步骤
5.发现其中有个Row Count Spool 占比较大 经过查阅资料 发现是与统计相关字段未建立索引 建立索引后优化27s左右
6.发现有复杂的更新子查询 但是不同更新数据又有上下父子级联动数据影响 检查后当前业务逻辑正确所以优化结束 增加参数过滤数据
7.对比 优化前1m多 优化后10s多
知识点
ROW_NUMBER()用法
语法: ROW_NUMBER() OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )
使用方式一:
select t.* from(
select ROW_NUMBER() over(order by id desc) as rownum,*
from TestA
) t
where rownum between 2 and 3 order by T4
使用方式二:
;with orderSection as
(
select ROW_NUMBER() OVER(order by id desc) rownum,* from TestA
)
select * from [orderSection] where rownum between 2 and 3
获取rownumber中排序的顺序 和主sql中的顺序应该一致 否则rownumber可能会不连续 感觉也没有不一致的场景。
增加PARTITION BY 的用法
若是在 T5 列上添加 PARTITION BY 子句,按照order by的顺序当 T5 值发生更改时将重新开始编号。 其实也是先按照T5排序,然后再按照T1排序
select ROW_NUMBER() over(partition by T5 order by T1 desc) as rownum,ID,T1,T5 from TestA
知识点
Rank()用法
语法: RANK() OVER ( [ partition_by_clause ] order_by_clause )
rank函数用于返回结果集的分区内每行的排名, 行的排名是相关行之前的排名数加一。简单来说rank函数就是对查询出来的记录进行排名,与row_number函数不同的是,rank函数考虑到了over子句中排序字段值相同的情况,如果使用rank函数来生成序号,over子句中排序字段值相同的序号是一样的,后面字段值不相同的序号将跳过相同的排名号排下一个,也就是相关行之前的排名数加一,可以理解为根据当前的记录数生成序号,后面的记录依此类推。
如 1,1,3,3,3,6
知识点
DENSE_RANK()用法
语法: DENSE_RANK() OVER ( [
] < order_by_clause > )
dense_rank函数的功能与rank函数类似,dense_rank函数在生成序号时是连续的,而rank函数生成的序号有可能不连续。dense_rank函数出现相同排名时,将不跳过相同排名号
如 1,1,2,2,2,3
知识点
NTILE()用法
语法:NTILE (integer_expression) OVER ( [
] < order_by_clause > )
参数 integer_expression:一个正整数表达式,用于指定每个分区必须被划分成的组数。 integer_expression 可以是 int 或 bigint 类型 。
关于该函数的说明:
如果分区的行数不能被 integer_expression 整除,则将导致一个成员有两种大小不同的组。 按照 OVER 子句指定的顺序,较大的组排在较小的组前面。 例如,如果总行数是 53,组数是 5,则前三个组每组包含 11 行,其余两个组每组包含 10 行。 另一方面,如果总行数可被组数整除,则行数将在组之间平均分布。 例如,如果总行数为 50,有五个组,则每组将包含 10 行。
select NTILE(2) over(order by T1 desc) as rownum,ID from TestA
分为两组 从1开始
1,1,2,2 或 1,1,1,2,2
知识点
SELECT - Order by 子句
语法:
ORDER BY order_by_expression
[ COLLATE collation_name ]
[ ASC | DESC ]
[ ,...n ]
[ ]
::=
{
OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS }
[
FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW | ROWS } ONLY
]
}
举个例子
ORDER BY EntryOrder OFFSET 1 ROWS
FETCH NEXT 10 ROWS ONLY
其中OFFSET后参数实际中可以为( @PageIndex * @PageSize ) - @PageSize
NEXT后参数可以为 @PageSize
知识点
链接服务器
添加链接服务器:exec sp_addlinkedserver '链接服务器名','','SQLOLEDB','服务器名或ip地址'
添加链接服务器登录方式:exec sp_addlinkedsrvlogin '链接服务器名','false',null,'数据库账号','密码'
删除链接服务器:exec sp_dropserver '链接服务器名称', 'droplogins' 第一个参数是要删除的链接服务器;第二个参数作用是连带删除该链接服务器登录映射
--如果存在则删除
IF EXISTS (SELECT srvname FROM master.dbo.sysservers srv WHERE srvid != 0 AND srvname = N'RDMDSDB')
EXEC master.dbo.sp_dropserver @server=N'RDMDSDB', @droplogins='droplogins'
--增加链接服务器
EXEC sp_addlinkedserver
@server='RDMDSDB', --被访问的服务器别名
@srvproduct='sqlserver', --SqlServer默认不需要写
@provider=N'SQLNCLI', --不同的库都是不一样的,OLE DB字符
@datasrc='nrdmdsdb.h3c.com'--要访问的服务器
GO
--增加登录方式
EXEC sp_addlinkedsrvlogin
@rmtsrvname='RDMDSDB', --被访问的服务器别名
@useself='false', --固定这么写
@locallogin=null, --本地操作应户名
@rmtuser='ISE_RDMDSNEW', --被访问的服务器用户名
@rmtpassword='NrdmdsDb4ISE43'--被访问的服务器用密码
GO
知识点
查看/操作 tempdb库
查看tempdb当前大小:exec sp_helpdb tempdb
对tempdb进行收缩:
use tempdb
go
dbcc shrinkfile(tempdev, 1024) --收缩文件
use tempdb
go
dbcc shrinkfile(templog, 512)--收缩日志
问题
不能创建大小为 9283 的行,该大小大于所允许的最大行大小 8060
每个表可以有1024列,表的行数及总大小仅受可用存储空间的限制,
每行最多可以存储8,060字节。
对于列过多导致行数据超过限定的情况,尽量不把数据放入表或临时表,直接取数或用CTE代替
知识点
统计某个字段中某个字符的个数
方法是把目标字符替换为空字符,再用原字符-替换后字符得到长度即可。
举个例子:统计“/”字符的个数
select len('888/6/35/1101')-len(replace('888/6/35/1101','/','')) from xxx
知识点
数据库作业用脚本展示 提升效率
原文链接:https://www.cnblogs.com/footleg/p/7131501.html
知识点
微软专家 一句话sql优化建议
1.in 中的值较多 建议反倒临时表中
2.select 中尽量不使用子查询
3.临时表 可以建索引
4.使用正向逻辑代替否定逻辑 e.g left join 替换 not in, not exits
5.isnull 函数用不到索引 应使用col is null or col=''
知识点
哪些情况需要建立索引
1.主键自动建立唯一索引
2.频繁作为查询条件的字段应该创建索引
3.查询中与其它表关联的字段,外键关联建立索引
4.频繁更新的字段不适合建索引(每次更新不单单是更新了记录还会更新索引)
5.where条件中用不到的字段不建索引
6.单键/组合索引(在高并发下建议建组合索引)
7.查询中排序的字段,排序字段通过索引去访问提高排序速度
8.查询中统计或分组字段
原文链接:https://blog.csdn.net/a332056918/article/details/81916255
知识点
子查询
子查询结果返回一个值(单行单列) 可以使用的运算符:><>=<==<>
select * from TestA
where T1 > ( select T1 from TestA where ID=2) ;
子查询结果返回多行(多行单列) 可以使用运算符:>ALL >ANY <ALL <ANY in
select * from TestA
where T1>All(select T1 from TestA where ID=2)
select * from TestA
where T1>Any(select T1 from TestA where ID=2)
子查询结果返回多行多列 在sqlserver中 需要使用运算符checksum辅助 oracle或Mysql中直接用(ColumnA,ColumnB)就可以
select * from TestA
where checksum(T1,T2) in
(
select checksum(T1,max(T2))
from TestA
group by T1
)
也可以用Exists 关键字 内外关联字段处理
关联子查询:关联子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。所以关联子查询,先执行主查询,再执行子查询
非关联子查询:是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。所以非关联子查询,先执行子查询,再执行主查询
坑
表中的字段最长为128 如果超出则会报错
实际中的报错:
消息 103,级别 15,状态 4,第 194 行
以 '1_solPart_15_LS-5130S-28S-EI;LS-5130S-28P-EI;LS-5130S-28P-HPWR-EI;LS-5130S-10P-HPWR-EI;S5110V2-28P-HPWR;5110V2-52P-PWR;S5120V2-2' 开头的 标识符 太长。最大长度为 128。
在有类似行转列操作时,部分数据由用户自己输入容易引发该问题。
最后解决办法是不使用名称而改用id作为列名,取出数据后到程序中再根据id找到名称。
知识点
使用try catch 以及相关报错信息
使用try catch的结构如下:
BEGIN TRY
需要捕捉异常的程序块
END TRY
BEGIN CATCH
异常处理块
END CATCH
ERROR_NUMBER() --返回错误代码
ERROR_SEVERITY() --返回错误的严重级别
ERROR_STATE() --返回错误的状态码
ERROR_MESSAGE() --返回错误的完整信息
知识点
数据随机排序 或 随机取数
这里主要用到了NewID() 函数,把它放在Order By 后即可:
SELECT * FROM TableA ORDER BY NEWID()
报错
已超过了锁请求超时时段 1222
现象:
1.执行truncate语句 一直得不到结果(应该很快完成才对)
2.所有表都刷新不出来
定位问题:
那么只有一种可能就是该TRUNCATE语句位于事务里面,而该事务由于逻辑原因等一直没有提交或回滚。
参考:https://www.cnblogs.com/kerrycode/p/4502164.html
错误一则
Insert语句与Foreign Key约束冲突
问题分析:
1.一般出现在表中建了外键的情况
2.该问题是在外键表中插入了不存在的主表的主键值
举例:
Create Table TestA
(
ID int primary key
)
Create Tabel TestB
(
ID int primary key,
WID int
)
Constraint FK_TestB_TestA(ID) References TestA
执行如下语句:
Insert Into TestB
Select 1,999
会报INSERT 语句与FOREIGN KEY约束FK_TestB_TestA冲突,该冲突发生在数据库XXXX,表dbo.TestA,Column 'ID'。语句已终止
知识点
设置自增表种子值
USE AdventureWorks2012;
GO
DBCC CHECKIDENT ('Person.AddressType', RESEED, 10);
GO
知识点
查询数据库中表,视图,存储过程,函数,触发器,用户定义类型的信息
所有表信息
SELECT name,create_date,modify_date
FROM sys.objects
WHERE type = 'U'
order by name
所有触发器
SELECT name AS 'Trigger Name', OBJECT_NAME(parent_id) AS 'Table Name',create_date,modify_date
FROM sys.triggers;
所有视图信息
SELECT name,create_date,modify_date
FROM sys.objects
WHERE type = 'V'
order by name
所有存储过程信息
SELECT name,create_date,modify_date
FROM sys.objects
WHERE type = 'P'
order by name
所有标量值函数
SELECT name,create_date,modify_date
FROM sys.objects
WHERE type = 'FN' AND is_ms_shipped = 0
order by name
所有表值函数
SELECT name,create_date,modify_date
FROM sys.objects WHERE type = 'TF'
UNION
SELECT name,create_date,modify_date
FROM sys.objects WHERE type = 'IF'
order by name
所有用户定义表类型
SELECT name
FROM sys.table_types
WHERE is_user_defined = 1
知识点
查询一个对象是什么类型
SELECT OBJECT_NAME(object_id) AS ObjectName,
CASE WHEN type = 'U' THEN 'Table'
WHEN type = 'V' THEN 'View'
WHEN type = 'P' THEN 'Stored Procedure'
ELSE ''
END AS ObjectType
FROM sys.objects
WHERE name IN ('对象名');
知识点
日期处理相关函数
YEAR() 函数:返回日期的年份
Year('2024-1-1') 结果:2024
MONTH() 函数:返回日期的月份。
Year('2024-1-1') 结果:1
DATEDIFF(interval,startdate,enddate) 函数:计算两个日期之间的差异。其中interval可以是年y,季度q,月m,日d,周w,小时h,分钟mi,秒s
DATEDIFF(DAY,'2024-1-1','2024-1-5') 结果:4